
#include "PicoInt.h"

//#define DEBUG_CPU

char PicoStatus[128]=""; // 68000 state for debug

#ifdef EMU_C68K
// ---------------------- Cyclone 68000 ----------------------

struct Cyclone PicoCpu;

int SekInit()
{
  memset(&PicoCpu,0,sizeof(PicoCpu));
  return 0;
}

// Reset the 68000:
int SekReset()
{
  if (Pico.rom==NULL) return 1;

  PicoCpu.srh =0x27; // Supervisor mode
  PicoCpu.a[7]=PicoCpu.read32(0); // Stack Pointer
  PicoCpu.membase=0;
  PicoCpu.pc=PicoCpu.checkpc(PicoCpu.read32(4)); // Program Counter

  return 0;
}


// Run the 68000 for 'cyc' number of cycles and return the number of cycles actually executed
static inline int DoRun(int cyc)
{
#ifdef DEBUG_CPU
  cyc=0;
#endif
  PicoCpu.cycles=cyc;
#ifdef DEBUG_CPU
  // Dump state
  printf("-----------------\n");
  int i;
  for(i=0;i<8;i++)
  {
    printf("d%d %08x ",i,PicoCpu.d[i]);
    if((i & 3) == 3)
      printf("\n");
  }
  for(i=0;i<8;i++)
  {
    printf("a%d %08x ",i,PicoCpu.a[i]);
    if((i & 3) == 3)
      printf("\n");
  }
  printf("PC %08x (%08x) ",PicoCpu.pc-PicoCpu.membase,PicoCpu.pc);
  printf("srh %02x xc %02x ccr %02x irq %02x ",PicoCpu.srh,PicoCpu.xc,PicoCpu.ccr,PicoCpu.irq);
  printf("osp %08x ",PicoCpu.osp);
  printf("membase %08x\n",PicoCpu.membase);
  // Dissassembly of current instruction
  char text[64];
  unsigned short *op = (unsigned short *)PicoCpu.pc;
  DisaPc = PicoCpu.pc-PicoCpu.membase;
  printf("%08x %04x ",DisaPc,*op);
  DisaText = text;
  DisaWord = PicoCpu.read16;
  DisaGet();
  printf("%s\n",text);
#endif
  
  CycloneRun(&PicoCpu);
  return cyc-PicoCpu.cycles;
}

int SekInterrupt(int irq)
{
  PicoCpu.irq=(unsigned char)irq;
  return 0;
}

int SekPc() { return PicoCpu.pc-PicoCpu.membase; }

void SekState(unsigned char *data)
{
  memcpy(data,PicoCpu.d,0x44);
}

#endif

#ifdef EMU_A68K
// ---------------------- A68K ----------------------

extern "C" void __cdecl M68000_RUN();
extern "C" void __cdecl M68000_RESET();
extern "C" int m68k_ICount=0;
extern "C" unsigned int mem_amask=0xffffff; // 24-bit bus
extern "C" unsigned int mame_debug=0,cur_mrhard=0,m68k_illegal_opcode=0,illegal_op=0,illegal_pc=0,opcode_entry=0; // filler

static int IrqCallback(int) { return -1; }
static int DoReset() { return 0; }
static int (*ResetCallback)()=DoReset;

int SekInit()
{
  memset(&M68000_regs,0,sizeof(M68000_regs));
  M68000_regs.IrqCallback=IrqCallback;
  M68000_regs.pResetCallback=ResetCallback;
  M68000_RESET(); // Init cpu emulator
  return 0;
}

int SekReset()
{
  // Reset CPU: fetch SP and PC
  M68000_regs.srh=0x27; // Supervisor mode
  M68000_regs.a[7]=PicoRead32(0);
  M68000_regs.pc  =PicoRead32(4);
  PicoInitPc(M68000_regs.pc);

  return 0;
}

static inline int DoRun(int cyc)
{
  m68k_ICount=cyc;
  M68000_RUN();
  return cyc-m68k_ICount;
}

int SekInterrupt(int irq)
{
  M68000_regs.irq=irq; // raise irq (gets lowered after taken)
  return 0;
}

int SekPc() { return M68000_regs.pc; }

void SekState(unsigned char *data)
{
  memcpy(data,      M68000_regs.d, 0x40);
  memcpy(data+0x40,&M68000_regs.pc,0x04);
}

#endif

#ifdef EMU_NULL
// -----------------------------------------------------------
int SekInit() { return 0; }
int SekReset() { return 0; }
static inline int DoRun(int cyc) { return cyc; }
int SekInterrupt(int) { return 0; }

int SekPc()
{
  return 0;
}

void SekState(unsigned char *) { }

#endif

int SekRun(int cyc)
{
  int did=0;

  did=DoRun(cyc);

  return did;
}
